package com.qdxwx.quartz.controller;

import com.qdxwx.common.annotation.Permissions;
import com.qdxwx.common.exception.job.TaskException;
import com.qdxwx.common.json.AjaxResult;
import com.qdxwx.common.page.PageRequest;
import com.qdxwx.common.page.TableDataInfo;
import com.qdxwx.common.utils.TKConvert;
import com.qdxwx.common.utils.TKString;
import com.qdxwx.quartz.domain.Job;
import com.qdxwx.quartz.service.JobService;
import com.qdxwx.quartz.util.CronUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 调度任务信息操作处理
 * 
 * @author qdxwx
 */
@Controller
@RequestMapping("/monitor/job")
public class JobController
{
    private String prefix = "monitor/job";

    @Autowired
    private JobService jobService;

    @Permissions("monitor:job:list")
    @GetMapping("/list.html")
    public String job()
    {
        return prefix + "/job";
    }

    @Permissions("monitor:job:list")
    @PostMapping("/list.json")
    @ResponseBody
    public TableDataInfo list(HttpServletRequest request, Job job)
    {
        List<Job> list = jobService.getList(job, PageRequest.form(request));
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(0);
        rspData.setRows(list);
        rspData.setTotal(jobService.count(job));
        return rspData;
    }

    //@Log(title = "定时任务", businessType = BusinessType.DELETE)
    @Permissions("monitor:job:remove")
    @PostMapping("/remove.json")
    @ResponseBody
    public AjaxResult remove(String ids) throws SchedulerException
    {
        jobService.deleteJobByIds(ids);
        return AjaxResult.success();
    }

    @Permissions("monitor:job:detail")
    @GetMapping("/detail/{jobId}")
    public String detail(@PathVariable("jobId") Long jobId, ModelMap mmap)
    {
        mmap.put("name", "job");
        mmap.put("job", jobService.selectJobById(jobId));
        return prefix + "/detail";
    }

    /**
     * 任务调度状态修改
     */
    //@Log(title = "定时任务", businessType = BusinessType.UPDATE)
    @Permissions("monitor:job:changeStatus")
    @PostMapping("/changeStatus.json")
    @ResponseBody
    public AjaxResult changeStatus(Job job) throws SchedulerException
    {
        Job newJob = jobService.selectJobById(job.getJobId());
        newJob.setStatus(job.getStatus());
        return AjaxResult.success(jobService.changeStatus(newJob));
    }

    /**
     * 任务调度立即执行一次
     */
    //@Log(title = "定时任务", businessType = BusinessType.UPDATE)
    @Permissions("monitor:job:changeStatus")
    @PostMapping("/run.json")
    @ResponseBody
    public AjaxResult run(Job job) throws SchedulerException
    {
        jobService.run(job);
        return AjaxResult.success();
    }

    /**
     * 新增调度
     */
    @GetMapping("/add.html")
    public String add()
    {
        return prefix + "/add";
    }

    /**
     * 新增保存调度
     */
    //@Log(title = "定时任务", businessType = BusinessType.INSERT)
    @Permissions("monitor:job:add")
    @PostMapping("/add.json")
    @ResponseBody
    public AjaxResult addSave(HttpServletRequest request) throws SchedulerException, TaskException
    {
        String jobName = request.getParameter("jobName");
        if (TKString.isEmpty(jobName)) return AjaxResult.error("任务名称不能为空");
        String jobGroup = request.getParameter("jobGroup");
        if (TKString.isEmpty(jobGroup)) return AjaxResult.error("请选择任务分组");
        String invokeTarget = request.getParameter("invokeTarget");
        if (TKString.isEmpty(invokeTarget)) return AjaxResult.error("调用目标字符串不能为空");
        String cronExpression = request.getParameter("cronExpression");
        if (TKString.isEmpty(cronExpression)) return AjaxResult.error("cron表达式不能为空");
        String misfirePolicy = request.getParameter("misfirePolicy");
        if (TKString.isEmpty(misfirePolicy)) return AjaxResult.error("请选择执行策略");
        String concurrent = request.getParameter("concurrent");
        if (TKString.isEmpty(concurrent)) return AjaxResult.error("请选择是否并发执行");
        Job job = new Job();
        job.setStatus("1");//默认任务暂停
        job.setJobName(jobName);
        job.setJobGroup(jobGroup);
        job.setInvokeTarget(invokeTarget);
        job.setCronExpression(cronExpression);
        job.setMisfirePolicy(misfirePolicy);
        job.setConcurrent(concurrent);
        job.setRemark(request.getParameter("remark"));
        return AjaxResult.success(jobService.insertJob(job));
    }

    /**
     * 修改调度
     */
    @GetMapping("/edit/{jobId}")
    public String edit(@PathVariable("jobId") Long jobId, ModelMap mmap)
    {
        mmap.put("job", jobService.selectJobById(jobId));
        return prefix + "/edit";
    }

    /**
     * 修改保存调度
     */
    //@Log(title = "定时任务", businessType = BusinessType.UPDATE)
    @Permissions("monitor:job:edit")
    @PostMapping("/edit.json")
    @ResponseBody
    public AjaxResult editSave(HttpServletRequest request) throws SchedulerException, TaskException
    {
        long jobId = TKConvert.toLong(request.getParameter("jobId"));
        if(jobId < 1) return AjaxResult.error("参数异常，jobId="+jobId);
        Job job = jobService.selectJobById(jobId);
        if (job == null) return AjaxResult.error("数据异常，jobId="+jobId);
        String jobName = request.getParameter("jobName");
        if (TKString.isEmpty(jobName)) return AjaxResult.error("任务名称不能为空");
        String jobGroup = request.getParameter("jobGroup");
        if (TKString.isEmpty(jobGroup)) return AjaxResult.error("请选择任务分组");
        String invokeTarget = request.getParameter("invokeTarget");
        if (TKString.isEmpty(invokeTarget)) return AjaxResult.error("调用目标字符串不能为空");
        String cronExpression = request.getParameter("cronExpression");
        if (TKString.isEmpty(cronExpression)) return AjaxResult.error("cron表达式不能为空");
        String misfirePolicy = request.getParameter("misfirePolicy");
        if (TKString.isEmpty(misfirePolicy)) return AjaxResult.error("请选择执行策略");
        String concurrent = request.getParameter("concurrent");
        if (TKString.isEmpty(concurrent)) return AjaxResult.error("请选择是否并发执行");
        job.setJobName(jobName);
        job.setJobGroup(jobGroup);
        job.setInvokeTarget(invokeTarget);
        job.setCronExpression(cronExpression);
        job.setMisfirePolicy(misfirePolicy);
        job.setConcurrent(concurrent);
        job.setRemark(request.getParameter("remark"));
        return AjaxResult.success(jobService.updateJob(job));
    }

    /**
     * 校验cron表达式是否有效
     */
    @PostMapping("/checkCronExpressionIsValid.json")
    @ResponseBody
    public boolean checkCronExpressionIsValid(Job job)
    {
        return CronUtils.isValid(job.getCronExpression());
    }
}
